<?php
/**
 * Created by : PhpStorm
 * User: 阿城 <479468212@qq.com>
 * Date: 2019/12/27
 * Time: 13:02
 */

namespace app\api\controller;

use app\api\controller\Base;
use app\api\model\User;
use app\api\model\UserData;
use app\util\Tools;

class Index extends Base
{

    /**
     * @OA\Get(
     *   path="/api/index",
     *   tags={"公共接口"},
     *   summary="前台首页",
     *   @OA\Response(response=200, description="Success")
     * )
     */
    public function index()
    {
        $this->success('公共首页访问成功！', []);
    }

     /**
     * @OA\Get(
     *   path="/api/version/check",
     *   tags={"客户端相关"},
     *   summary="版本更新",
     *   @OA\Parameter(ref="#/components/parameters/AppClientVersion"),
     *   @OA\Parameter(ref="#/components/parameters/AppDeviceType"),
     *   @OA\Parameter(name="app_id",in="query",description="APP包名APP_ID", @OA\Schema( type="string")),
     *   @OA\Parameter(name="version",in="query",description="APP当前版本号，格式1.0.0", @OA\Schema( type="string")),
     *   @OA\Response(
     *     response="200",
     *     description="返回字段描述：version最新版本号、is_force是否强制更新1是0否、wgt_url增量更新地址、update_url全量更新地址、describe描述",
     *     @OA\MediaType(
     *      mediaType="application/json",
     *      @OA\Schema(
     *         @OA\Property(property="code", type="number",description="状态码"),
     *         @OA\Property(property="msg", type="string",description="提示消息"),
     *         @OA\Property(property="data", type="object",description="数据列表",@OA\Items),
     *      )
     *    )
     *   ),
     *   @OA\Response(response="500", description="服务器错误"),
     *   security={{"App-Login-Token": ""}}
     * )
     */
    public function checkVersion()
    {
        $appId = $this->request->get('app_id');
        $version = $this->request->get('version');
        $version = str_replace(".", "", $version);
        $result = upgradeModel::where(['app_id' => $appId, 'status' => 1])->order('id DESC')->find();
        if ((!empty($result) && str_replace(".", "", $result['version']) > $version) || ($version == 'undefined')) {
            $this->success('有新版本', ['version' => $result['version'], 'is_force' => $result['is_force'], 'wgt_url' => $result['wgt_url'], 'update_url' => $result['update_url'], 'describe' => $result['describe']]);
        } else {
            $this->error('没有更新');
        }
    }

    /**
     * @OA\Post(
     *     path="/api/login",
     *     tags={"用户相关"},
     *     summary="用户登录",
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema(
     *                 @OA\Property(property="username", type="string", description="用户名"),
     *                 @OA\Property(property="password", type="string", description="密码"),
     *                 example={"username": "test", "password": "123456"}
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="OK"
     *     )
     * )
     */
    public function login()
    {
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        if (!$username) {
            $this->error('缺少用户名!');
        }
        if (!$password) {
            $this->error('缺少密码!');
        } else {
            $password = Tools::userMd5($password);
        }
        $field = 'id,username,nickname,type,status,phone,email,real_status,realname';
        $userInfo = User::field($field)->where(['username' => $username, 'password' => $password])->find();
        if (!empty($userInfo)) {
            if ($userInfo['status']) {
                //更新用户数据
                $userData = $userInfo->userData;
                $data = [];
                if ($userData) {
                    $userData->login_times++;
                    $userData->last_login_ip = $this->request->ip();
                    $userData->last_login_time = time();
                    $userData->save();
                } else {
                    $data['login_times'] = 1;
                    $data['uid'] = $userInfo['id'];
                    $data['last_login_ip'] = $this->request->ip();
                    $data['last_login_time'] = time();
                    $data['avatar'] = '';
                    UserData::create($data);
                    $data['preview_avatar_url'] = '';
                    $userInfo['userData'] = $data;
                }
            } else {
                $this->error('用户已被封禁，请联系管理员');
            }
        } else {
            $this->error('用户名密码不正确');
        }
        //设置登陆缓存
        $findToken = cache('Login:' . $userInfo['id']);
        if(!empty($findToken)){
            cache('Login:' . $findToken, null);
        }
        $LoginToken = md5(uniqid() . time());
        cache('Login:' . $LoginToken, json_encode($userInfo), config('easyApi.ONLINE_TIME'));
        cache('Login:' . $userInfo['id'], $LoginToken, config('easyApi.ONLINE_TIME'));
        $userInfo['LoginToken'] = $LoginToken;
        $this->success('登录成功！',$userInfo);
    }

    /**
     * @OA\Get(
     *   path="/api/logout",
     *   tags={"用户相关"},
     *   summary="用户登出",
     *   @OA\Response(response=200, description="Success")
     * )
     */
    public function logout() {
        $loginToken = $this->request->header('App-Login-Token');
        cache('Login:' . $loginToken, null);
        cache('Login:' . $this->userId, null);
        $this->success('登出成功');
    }

    /**
     * @OA\Post(
     *     path="/api/register",
     *     tags={"用户相关"},
     *     summary="用户注册",
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema(
     *                 @OA\Property(property="username", type="string", description="用户名"),
     *                 @OA\Property(property="password", type="string", description="密码"),
     *                 @OA\Property(property="code", type="string", description="验证码"),
     *                 @OA\Property(property="referrer_id", type="integer", description="推荐人ID"),
     *                 example={"username": "test", "password": "123456", "code":"123456","referrer_id":3}
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="OK"
     *     )
     * )
     */
    public function register()
    {
        $username   = $this->request->post('username');
        $password   = $this->request->post('password');
        $code       = $this->request->post('code');
        $referrerId = $this->request->post('referrer_id', 0);
        $registerConfig = config('register');

        if (!$username) {
            $this->error('缺少用户名!');
        }
        if (!$password) {
            $this->error('缺少密码!');
        }
        if (filter_var($username, FILTER_VALIDATE_EMAIL)) {
            $type = 'ems';
        } else {
            $type = 'sms';
        }

        // 开启验证码验证
        if (!empty($registerConfig['isSmsVerification']) && !verification_CAPTCHA($username, $code, $type, 'register')) {
            $this->error('验证码错误!');
        }

        // 开启邀请注册
        if(!empty($registerConfig['isNeedInvitation'])){
            if (!$referrerId) {
                $this->error('缺少推荐人');
            }
            if (!$code) {
                $this->error('缺少验证码!');
            }
            $referrer = User::where(['id' => $referrerId])->find();
            if(empty($referrer)){
                $this->error('推荐人不存在!');
            }
            if($referrer['status'] != 1){
                $this->error('推荐人状态异常!');
            }
            $referrer = $referrer->toArray();
        }
        $password = Tools::userMd5($password);
        $userInfo = User::where(['username|phone|email' => $username])->find();
        if (!empty($userInfo)) {
            $this->error('用户已存在');
        }
        $data = [];
        $data['username'] = $username;
        if($type == 'sms'){
            $data['phone'] = $username;
        }else{
            $data['email'] = $username;
        }
        $data['password'] = $password;
        $data['referrer_id'] = $referrerId;
        if(!empty($referrer)){
            if(strlen($referrer['referrer_id_path']) <= 0){
                $referrer['referrer_id_path'] = '0';
            }
            $data['referrer_id_path'] = $referrer['referrer_id_path'].','.$referrerId;
            $data['referrer_level'] = $referrer['referrer_level']+1;
        }else{
            $referrer['referrer_id_path'] = '0';
        }
        $data['create_time'] = time();
        $data['create_ip'] = $this->request->ip();
        $result = User::create($data);
        if(!$result){
            $this->error('创建用户失败');
        }
        $this->success('成功！');
    }

    /**
     * @OA\Post(
     *     path="/api/findPassword",
     *     tags={"用户相关"},
     *     summary="找回密碼",
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema(
     *                 @OA\Property(property="phone", type="string", description="手機號"),
     *                 @OA\Property(property="password", type="string", description="密码"),
     *                 @OA\Property(property="code", type="string", description="验证码"),
     *                 example={"phone": "1888503864", "password": "123456", "code":"1234"}
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="OK"
     *     )
     * )
     */
    public function findPassword()
    {
        $phone = $this->request->post('phone');
        $password = $this->request->post('password');
        $code = $this->request->post('code');
        if (!$phone) {
            $this->error('缺少手機號!');
        }
        if (!$password) {
            $this->error('缺少密碼!');
        }
        if (!$code) {
            $this->error('缺少驗證碼!');
        }
        if (filter_var($phone, FILTER_VALIDATE_EMAIL)) {
            $type = 'ems';
        } else {
            $type = 'sms';
        }
        if (!verification_CAPTCHA($phone, $code, $type, 'findpassword')) {
            $this->error('驗證碼錯誤!');
        }
        $password = Tools::userMd5($password);
        $userInfo = User::where(['username' => $phone])->find();
        if (empty($userInfo)) {
            $this->error('用戶不存在');
        }
        $userInfo->password = $password;
        $result = $userInfo->save();
        if (!$result) {
            $this->error();
        }
        $this->success();
    }

    /**
     * @OA\Post(
     *     path="/api/getCAPTCHA",
     *     tags={"用户相关"},
     *     summary="获取验证码",
     *     @OA\RequestBody(
     *         @OA\MediaType(
     *             mediaType="application/json",
     *             @OA\Schema(
     *                 @OA\Property(property="receive", type="string", description="接收验证码对象"),
     *                 @OA\Property(property="type", type="string", description="驗證碼類型，sms短信、ems邮件"),
     *                 @OA\Property(property="scene", type="string", description="使用场景，register注册、login登录、findpassword找回密码、transaction交易"),
     *                 @OA\Property(property="area_code", type="string", description="区域代码，邮箱无该参数，+86中国、+52中国香港……"),
     *                 example={"receive": "123@qq.com","type": "ems","scene": "register","area_code": "+86"}
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="OK"
     *     )
     * )
     */
    public function getCAPTCHA()
    {
        $receive = $this->request->post('receive');
        $type = $this->request->post('type', 'sms');// 验证码类型
        $scene = $this->request->post('scene');// 验证场景类型
        $areaCode = $this->request->post('area_code');

        $isEmail = false;
        if (!filter_var($receive, FILTER_VALIDATE_EMAIL)) {
            if (strlen($receive) != 11) {
                $this->error('手機號錯誤!');
            }
        } else {
            $isEmail = true;
        }
        if (verification_CAPTCHA($receive, '', $type, $scene)) {
            $this->success("请使用最近的一次验证码，15分钟内可连续使用");
        }

        $code = StrRandom::randomNumber();
        $key = "$type:$receive";
        if ($scene) {
            $key = "$type:$scene:$receive";
        }
        if ($isEmail) {
            $text = '【卢卡生态】您的邮箱验证码是' . ($code);
            $result = $this->send_email($receive, $text);
            if ($result['msg'] != '发送成功') {
                $this->error('发送失败', $result);
            }
        } else {
            $text = '【卢卡生态】您的手机验证码是' . ($code);
            $result = $this->send_code($receive, $text);
            if ($result['msg'] != '发送成功') {
                $this->error('发送失败', $result);
            }
        }
        cache($key, $code, 900);
        $this->success();
    }

    private function send_email($email, $text)
    {
        header("Content-Type:text/html;charset=utf-8");
        try {
            //Server settings
            $formEmail = $email;
            $mail = new \PHPMailer\PHPMailer\PHPMailer();
            $mail->isSMTP();
            $mail->CharSet = "UTF-8";
            $mail->Encoding = 'base64';
            $mail->Host = 'ssl://smtp.gmail.com';
            $mail->SMTPAuth = true;
            $mail->Username = 'Lucca.Ecol.Ltd@gmail.com';
            $mail->Password = 'lucca12345';
            $mail->Port = 465;

            //Recipients
            $mail->setFrom($formEmail, '卢卡生态');
            $mail->addAddress($email);

            // Content
            $mail->isHTML(true);                                  // Set email format to HTML
            $mail->Subject = '【卢卡生态】验证码';
            $mail->Body = $text;

            $res = $mail->send();
            if ($res) {
                return ['code' => 0, 'msg' => '发送成功'];
            } else {
                return ['code' => -1, 'msg' => '未知错误'];
            }
        } catch (Exception $e) {
            return ['code' => -1, 'msg' => $mail->ErrorInfo];
        }
    }

    private function send_code($mobile, $text)
    {
        header("Content-Type:text/html;charset=utf-8");
        $apikey = config('easyApi.YUNPIAN_SMS_API_KEY');
        $mobile = $mobile; //请用自己的手机号代替
        $text = $text;
        $ch = curl_init();

        /* 设置验证方式 */
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept:text/plain;charset=utf-8', 'Content-Type:application/x-www-form-urlencoded', 'charset=utf-8'));
        /* 设置返回结果为流 */
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        /* 设置超时时间*/
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);

        /* 设置通信方式 */
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $data = array('text' => $text, 'apikey' => $apikey, 'mobile' => $mobile);
        $json_data = $this->send($ch, $data);
        return json_decode($json_data, true);
    }

    private function send($ch, $data)
    {
        curl_setopt($ch, CURLOPT_URL, 'https://sms.yunpian.com/v2/sms/single_send.json');
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        $result = curl_exec($ch);
        return $result;
    }


    /**
     * @OA\Get(
     *   path="/api/config",
     *   tags={"配置相关"},
     *   summary="获取配置",
     *   @OA\Parameter(ref="#/components/parameters/AppClientVersion"),
     *   @OA\Parameter(ref="#/components/parameters/AppDeviceType"),
     *   @OA\Parameter(name="key",in="query",description="配置键名，如不传则返回数组格式全部数据", @OA\Schema( type="string")),
     *   @OA\Response(
     *     response="200",
     *     description="返回字段描述：siteName站点名称、LACBury-LAC剩余量、LAGBury-LAG剩余量、withdrawFeeRate提币费率、withdrawMinAmount最低起提",
     *     @OA\MediaType(
     *      mediaType="application/json",
     *      @OA\Schema(
     *         @OA\Property(property="code", type="number",description="状态码"),
     *         @OA\Property(property="msg", type="string",description="提示消息"),
     *         @OA\Property(property="data", type="object",description="数据列表",@OA\Items),
     *      )
     *    )
     *   ),
     *   @OA\Response(response="500", description="服务器错误"),
     *   security={{"App-Login-Token": ""}}
     * )
     */
    public function config()
    {
        $key = $this->request->get('key');
        if (empty($key)) {
            $key = 'systemConfig';
        } else {
            $key = 'systemConfig.' . $key;
        }
        $config = config($key);
        $this->success('成功', $config);
    }
    
}
